home *** CD-ROM | disk | FTP | other *** search
/ MacWorld 1999 September (IDG) / Sep99.iso / Shareware World / Utilities / Text Processing / Alpha / Tcl / Modes / latex Mode / latexComm.tcl < prev    next >
Encoding:
Text File  |  1999-05-05  |  16.5 KB  |  570 lines  |  [TEXT/ALFA]

  1. #############################################################################
  2. #############################################################################
  3. #
  4. # latexComm.tcl (called from latex.tcl)
  5. #
  6. #############################################################################
  7. #
  8. # Old Author:  Tom Scavo <trscavo@syr.edu>
  9. # New Author:  Vince Darley <darley@fas.harvard.edu>
  10. #############################################################################
  11. #############################################################################
  12.  
  13. proc latexComm.tcl {} {}
  14. #--------------------------------------------------------------------------
  15. # TeX applications
  16. #--------------------------------------------------------------------------
  17.  
  18. # In the following scripts, $quotedSig and $filename are the application 
  19. # signature and the name of the file to be typeset, respectively.  (See
  20. # proc 'evalTeXScript' below.)
  21. array set bibtexAppScripts {
  22.     DirectTeXPro {
  23.     {dosc -c $quotedSig -s  "ProjectMgr -t \$dt_TeXFormat    \"[win::Current]\"; MenuCommand 1 5"}
  24.     } CMacTeX {
  25.     {sendOpenEvent noReply $quotedSig $filename}
  26.     } BibTeX {
  27.     {sendOpenEvent noReply $quotedSig $filename}
  28.     }
  29. }
  30. array set bibtexAppSignatures {
  31.     CMacTeX CMTu BibTeX Vbib
  32. }
  33. array set dvipsAppScripts {
  34.     DirectTeXPro {
  35.     {dosc -c $quotedSig -s  "ProjectMgr -t \$dt_TeXFormat    \"[win::Current]\";  directory \$dt_TeXProjectDir > CurrDirectory; dvips \$dt_TeXProjectName"}
  36.     } CMacTeX {
  37.     {dosc -c $quotedSig -k 'aevt' -e 'odoc' -t 600 -f $filename}
  38.     } OzTeX {
  39.     {sendOpenEvent noReply $quotedSig $filename}
  40.     }
  41. }
  42. array set dvipsAppSignatures {
  43.     DirectTeXPro TeX+ CMacTeX CMT1 OzTeX OzDP
  44. }
  45. array set makeindexAppScripts {
  46.     DirectTeXPro {
  47.     {dosc -c $quotedSig -s  "ProjectMgr -t \$dt_TeXFormat    \"[win::Current]\"; MenuCommand 1 6"}
  48.     } CMacTeX {
  49.     {sendOpenEvent noReply $quotedSig $filename}
  50.     } MakeIndex {
  51.     {sendOpenEvent noReply $quotedSig $filename}
  52.     }
  53. }
  54. array set makeindexAppSignatures {
  55.     DirectTeXPro TeX+ CMacTeX CMTt MakeIndex RZMI
  56. }
  57. array set printDVIAppScripts {
  58.     Textures {
  59.     {AEBuild $quotedSig aevt pdoc "----" [makeAlis $filename]}
  60.     } DirectTeXPro {
  61.     {dosc -c $quotedSig -s  "ProjectMgr -t \$dt_TeXFormat    \"[win::Current]\"; MenuCommand 1 9"}
  62.     } CMacTeX {
  63.     {dosc -c $quotedSig -k 'aevt' -e 'pdoc' -r -f $filename}
  64.     } OzTeX {
  65.     {dosc -c $quotedSig -k 'aevt' -e 'pdoc' -r -f $filename}
  66.     }
  67. }
  68. array set printDVIAppSignatures {
  69.     Textures *TEX DirectTeXPro TeX+ CMacTeX CMT8 OzTeX OTEX
  70. }
  71. array set printPSAppScripts {
  72.     DropPS {
  73.     {dosc -c $quotedSig -k 'aevt' -e 'odoc' -r -f $filename}
  74.     } DirectTeXPro {
  75.     {dosc -c $quotedSig -s  "ProjectMgr -t \$dt_TeXFormat    \"[win::Current]\";  directory \$dt_TeXProjectDir > CurrDirectory; download \$dt_TeXProjectName.ps"}
  76.     } CMacTeX {
  77.     {dosc -c $quotedSig -k 'aevt' -e 'odoc' -r -f $filename}
  78.     }
  79. }
  80. array set printPSAppSignatures {
  81.     DropPS D•PS DirectTeXPro TeX+ CMacTeX PSP*
  82. }
  83. array set texAppScripts {
  84.     DirectTeX {
  85.     {set script "Begin; ChangeTeXProject '$filename' -check -confirm || Exit 0;  Execute \"{dt_TeXProject}\"; TeXMenu -tex -formats;  End ∑ Dev:Null; RunSession 1 ∑ Dev:Null"} 
  86.     {dosc -r -c $quotedSig -s $script} 
  87.     } Textures {
  88.     {global Texturesconnections} 
  89.     {set TeXjob ""} 
  90.     {
  91.         if {[info exists Texturesconnections]} {
  92.         foreach entry $Texturesconnections {
  93.             if {[car $entry] == $filename} {
  94.             set TeXjob [lindex $entry 1]
  95.             break
  96.             }
  97.         }
  98.         }
  99.     }   
  100.     {
  101.         if { $TeXjob == "" } {
  102.         set TeXjob [AEBuild -r $quotedSig BSRs Begi]
  103.         set TeXjob [string trim [string range $TeXjob 15 end] {\{\}\"}]
  104.         lappend Texturesconnections [list $filename $TeXjob]
  105.         }
  106.     }   
  107.     {AEBuild -t 1200 $quotedSig BSRs Typs "----" [makeAlis $filename] fmat {"LaTeX"} Jobi $TeXjob} 
  108.     } DirectTeXPro {
  109.     {dosc -c $quotedSig -s  "if \$dt_TeXFormat = \'\' \"set dt_TeXFormat -x \$dt_DefaultFormat\""} 
  110.     {dosc -c $quotedSig -s  "ProjectMgr -t \$dt_TeXFormat \"$filename\"; MenuCommand 1 4"} 
  111.     } CMacTeX {
  112.     {dosc -c $quotedSig -k 'aevt' -e 'odoc' -r -f $filename}
  113.     } OzTeX {
  114.     {sendOpenEvent noReply $quotedSig $filename}
  115.     } 
  116. }
  117. array set texAppSignatures {
  118.     DirectTeX MPS* Textures *TEX DirectTeXPro TeX+ 
  119.     CMacTeX {*XeT BTxT pXeT} OzTeX OTEX
  120. }
  121. array set viewDVIAppScripts {
  122.     Textures {
  123.     {AEBuild $quotedSig aevt odoc "----" [makeAlis $filename]}
  124.     } DirectTeXPro {
  125.     {dosc -c $quotedSig -s "ProjectMgr -t \$dt_TeXFormat    \"[win::Current]\"; MenuCommand 1 8"}
  126.     } CMacTeX {
  127.     {dosc -c $quotedSig -k 'aevt' -e 'odoc' -r -f $filename}
  128.     } OzTeX {
  129.     {sendOpenEvent noReply $quotedSig $filename}
  130.     }
  131. }
  132. array set viewDVIAppSignatures {
  133.     Textures *TEX DirectTeXPro TeX+ CMacTeX {PIVD CMT8} OzTeX OTEX
  134. }
  135. array set viewPSAppScripts {
  136.     CMacTeX {
  137.     {dosc -c $quotedSig -k 'aevt' -e 'odoc' -r -f $filename}
  138.     } MacGS {
  139.     {dosc -c $quotedSig -k 'aevt' -e 'odoc' -r -f $filename}
  140.     } Tailor {
  141.     {dosc -c $quotedSig -k 'aevt' -e 'odoc' -r -f $filename}
  142.     }
  143. }
  144. array set viewPSAppSignatures {
  145.     CMacTeX {CMT5 CMTJ TMCJ} MacGS gsVR Tailor Tail
  146. }
  147. array set viewPDFAppScripts {
  148.     CMacTeX {
  149.     {dosc -c $quotedSig -k 'aevt' -e 'odoc' -r -f $filename}
  150.     } MacGS {
  151.     {dosc -c $quotedSig -k 'aevt' -e 'odoc' -r -f $filename}
  152.     } Acrobat {
  153.     {sendOpenEvent noReply $quotedSig $filename}
  154.     }
  155. }
  156. array set viewPDFAppSignatures {
  157.     MacGS gsVR Acrobat CARO CMacTeX CMTJ
  158. }
  159.  
  160. #--------------------------------------------------------------------------
  161. # Typeset submenu commands
  162. #--------------------------------------------------------------------------
  163.  
  164. proc typeset {{bg 0}} {
  165.     # Is there a window open?
  166.     set currentWin [win::Current]
  167.     if { $currentWin == "" } {
  168.     typesetFile "" $bg
  169.     return
  170.     }
  171.     # Strip off trailing garbage (if any):
  172.     regexp {(.*) <[0-9]+>} $currentWin dummy currentWin
  173.     # Is the current window part of TeX fileset?
  174.     set fset [isWindowInFileset $currentWin "tex"]
  175.     if { $fset != "" } {
  176.     if [dirtyFileset $fset] {
  177.         switch [askyesno -c "Save current TeX fileset?"] {
  178.         "yes" {saveEntireFileset $fset}
  179.         "no" {
  180.             # do nothing
  181.         }
  182.         "cancel" {return}
  183.         }
  184.     }
  185.     typesetFile [texFilesetBaseName $fset] $bg
  186.     return
  187.     }
  188.     # Is the window untitled or dirty?
  189.     global PREFS
  190.     set currentDoc [file tail $currentWin]
  191.     if { [set num [winUntitled]] } {
  192.     switch [askyesno -c "Save \"$currentDoc\"?"] {
  193.         "yes" {
  194.         if {[catch {set currentWin [saveAs "Untitled$num\.tex"]}]} {return}
  195.         }
  196.         "no" {
  197.         set tmpFilename "Untitled$num\.tex"
  198.         set text [getText [minPos] [maxPos]]
  199.         if {![file exists [file join $PREFS tmp]]} { mkdir [file join $PREFS tmp] }
  200.         set newDoc [file join $PREFS tmp $tmpFilename]
  201.         file::writeAll $newDoc $text 1
  202.         set currentWin $newDoc
  203.         }
  204.         "cancel" {return}
  205.     }
  206.     } elseif { [winDirty] } {
  207.     switch [askyesno -c "Save \"$currentDoc\"?"] {
  208.         "yes" {save}
  209.         "no" {
  210.         set text [getText [minPos] [maxPos]]
  211.         if {![file exists [file join $PREFS tmp]]} { file mkdir [file join $PREFS tmp] }
  212.         set newDoc [file join $PREFS tmp temp-$currentDoc]
  213.         file::writeAll $newDoc $text 1
  214.         set currentWin $newDoc
  215.         }
  216.         "cancel" {return}
  217.     }
  218.     }
  219.     # Is the current window TeX-able?
  220.     set ext [file extension $currentWin]
  221.     if { [lsearch -exact {.tex .ltx .dtx .ins} $ext] < 0 } {
  222.     typesetFile "" $bg
  223.     return
  224.     }
  225.     typesetFile $currentWin $bg
  226. }
  227.  
  228. proc typesetSelection {} {
  229.     global PREFS TeX::tmpFile
  230.     if { [isSelection] } { 
  231.     watchCursor
  232.     message "processing selection…"
  233.     set currentWin [win::Current]
  234.     # Is the current window part of TeX fileset?
  235.     set fset [isWindowInFileset $currentWin "tex"]
  236.     if { $fset == "" } {
  237.         set pos1 [getPos]
  238.         if { [isInDocument] } {
  239.         set pos2 [selEnd]
  240.         if { [isInDocument] } {
  241.             # fall through
  242.         } else {
  243.             beep
  244.             set msg "Selection not in document environment.  Continue?"
  245.             if { [askyesno $msg] == "no" } { return }
  246.         }
  247.         } else {
  248.         beep
  249.         set msg "Selection not in document environment.  Continue?"
  250.         if { [askyesno $msg] == "no" } { return }
  251.         set pos2 [selEnd]
  252.         }
  253.         set body "\r[getText $pos1 $pos2]\r"
  254.         set searchText [getText [minPos] [maxPos]]
  255.     } else {
  256.         set body "\r[getSelect]\r"
  257.         # Will not handle a base file that is open and dirty:
  258.         set searchText [buildFilecontents [texFilesetBaseName $fset]]
  259.     }
  260.     message "building temporary document…"
  261.     set pattern {(\\documentclass.*)\\begin\{document\}}
  262.     if { ![regexp -- $pattern $searchText dummy preamble] } {
  263.         set preamble "\\documentclass\{article\}\r"
  264.     }
  265.     set rootFile [file rootname $currentWin]
  266.     set tempFile "temp-[file tail $rootFile]"
  267.     set auxFile $rootFile.aux
  268.     if { [file exists $auxFile] } {
  269.         set latexDoc [buildFilecontents $auxFile $tempFile.aux]
  270.     } else {
  271.         set latexDoc {}
  272.     }
  273.     append latexDoc $preamble [buildEnvironment "document" "" $body" "\r"]
  274.     set currentDir [file dirname $currentWin]
  275.     set latexDoc [texResolveAll $latexDoc $currentDir]
  276.     if {![file exists [file join $PREFS tmp]]} { file mkdir [file join $PREFS tmp] }
  277.     set newFile [file join $PREFS tmp $tempFile.tex]
  278.     file::writeAll $newFile $latexDoc 1
  279.     set lineOffset [expr {[llength [split $latexDoc "\r"]] - [llength [split $body "\r"]] -2}]
  280.     set TeX::tmpFile($newFile) [list selection $currentWin $lineOffset]
  281.     typesetFile $newFile
  282.     } else {
  283.     beep
  284.     message "no selection"
  285.     }
  286. }
  287.  
  288. proc typesetClipboard {} {
  289.     global PREFS TeX::tmpFile
  290.     set body "\r[getScrap]\r"
  291.     set pat1 {\\begin\{document\}.*\\end\{document\}}
  292.     set pat2 {\\documentclass}
  293.     set preamble "\\documentclass\{article\}\r"
  294.     # Check to see if there's a document environment:
  295.     if {![regexp -- $pat1 $body]} {
  296.     append text $preamble [buildEnvironment "document" "" $body "\r"]
  297.     } else {
  298.     # Check to see if there's a \documentclass command:
  299.     if {![regexp -- $pat2 $body]} {
  300.         append text $preamble $body
  301.     } else {
  302.         set text $body
  303.     }
  304.     }
  305.     if {![file exists [file join $PREFS tmp]]} { file mkdir [file join $PREFS tmp] }
  306.     set newFile [file join $PREFS tmp temp-noname\.tex]
  307.     file::writeAll $newFile $text 1
  308.     set currentWin $newFile
  309.     set TeX::tmpFile($newFile) "clipboard"
  310.     typesetFile $currentWin
  311. }
  312.  
  313. # Typeset $filename, but perform no error-checking
  314. #
  315. proc typesetFile {filename {bg 0}} {
  316.     if { $filename == "" } {
  317.     set filename [getfile "Choose a file to typeset:"]
  318.     }
  319.     evalTeXScript tex {TeX app} $filename $bg
  320. }
  321.  
  322. # Apply $op to a file with extension $ext.  (See latexMenu.tcl for
  323. # many examples.)  If 'forcecurrent == 1', use the current window 
  324. # even if it belongs to a TeX fileset.
  325. #
  326. proc doTypesetCommand {op ext {forcecurrent 0}} {
  327.     if { [set filename [findAuxiliaryFile $ext $forcecurrent]] != "" } {
  328.     if { $op == "open" } { 
  329.         edit -r -m -w $filename 
  330.     } else {
  331.         $op${ext}File $filename
  332.     }
  333.     } else {
  334.     beep
  335.     alertnote "No $ext file found!"
  336.     }
  337. }
  338.  
  339. proc viewDVIFile {filename} {
  340.     evalTeXScript viewDVI {DVI viewer} $filename
  341. }
  342.  
  343. proc viewPDFFile {filename} {
  344.     evalTeXScript viewPDF {PDF viewer} $filename
  345. }
  346.  
  347. proc printDVIFile {filename} {
  348.     evalTeXScript printDVI {DVI print driver} $filename
  349. }
  350.  
  351. proc dvipsDVIFile {filename} {
  352.     evalTeXScript dvips {DVI-to-PS filter} $filename
  353. }
  354.  
  355. proc viewPSFile {filename} {
  356.     if {[catch {evalTeXScript viewPS {PS viewer} $filename}]} {
  357.     message "View aborted."
  358.     }
  359. }
  360.  
  361. proc printPSFile {filename} {
  362.     evalTeXScript printPS {PS print driver} $filename
  363. }
  364.  
  365. proc bibtexAUXFile {filename} {
  366.     evalTeXScript bibtex {BibTeX app} $filename
  367. }
  368.  
  369. proc makeindexIDXFile {filename} {
  370.     evalTeXScript makeindex {MakeIndex app} $filename
  371. }
  372.  
  373. proc makeindexGLOFile {filename} {
  374.     evalTeXScript makeindex {MakeIndex app} $filename
  375. }
  376.  
  377. proc evalTeXScript {op prompt filename {runAppInBackground 0}} {
  378.     global showTeXLog
  379.     if {[info exists showTeXLog]} {
  380.     app::runScript $op $prompt $filename $runAppInBackground $showTeXLog
  381.     } else {
  382.     app::runScript $op $prompt $filename $runAppInBackground 0
  383.     }
  384.     # this code needs a mechanism for waiting for the TeX run to complete
  385.     if {0 && !$runAppInBackground && ($showTeXLog == 2)} {
  386.     set fname [file tail $filename]
  387.     set curr [file tail [win::Current]]
  388.     if {[file extension $curr] == ".log" && ([file root $fname] == [file root $curr])} {
  389.         return
  390.     } else {
  391.         set fname [file root $filename]
  392.         file::openQuietly ${fname}.log
  393.     }
  394.     }
  395. }
  396.  
  397. # Two bugs in 'getfile' (see "alpha.bugs58"):
  398. proc openAnyTeXFile {} {
  399.     set    filename [getfile "" [win::Current]]
  400.     if { ![string length $filename] } return
  401.     edit -r -m -w $filename
  402. }
  403.  
  404. proc removeAuxiliaryFiles {} {
  405.     set word ""
  406.     set removeSilently 0
  407.     set currentWin [win::Current]
  408.     if { $currentWin == "" } { return }
  409.     set currentDir [file dirname $currentWin]
  410.     set extensions {.ps .dvi .log .aux .bbl .idx .ind .glo .gls \
  411.       .toc .lof .lot .blg .ilg}
  412.     foreach ext $extensions {
  413.     message "Checking for *$ext files…"
  414.     set files [glob -nocomplain [file join $currentDir *$ext]]
  415.     foreach file $files {
  416.         set word " more"
  417.         if {$removeSilently} {
  418.         if {[catch {rm [file join $currentDir *$ext]}]} {
  419.             alertnote "not all \"*$ext\" files deleted"
  420.         }
  421.         break
  422.         } else {
  423.         message ""
  424.         set filename [file tail $file]
  425.         switch [buttonAlert "Remove \"$filename\"?" "yes" "no" {rm ext} {rm all} "cancel"] {
  426.             "yes" {
  427.             message "Removing $filename…"
  428.             if {[catch {removeFile [file join $currentDir $filename]}]} {
  429.                 alertnote "\"$filename\" not deleted"
  430.             } else {
  431.                 message $filename
  432.             }
  433.             }
  434.             "no" {}
  435.             "rm ext" {
  436.             if {[catch {rm [file join $currentDir *$ext]}]} {
  437.                 alertnote "not all \"*$ext\" files deleted"
  438.             }
  439.             break
  440.             }
  441.             "rm all" {
  442.             if {[catch {rm [file join $currentDir *$ext]}]} {
  443.                 alertnote "not all \"*$ext\" files deleted"
  444.             }
  445.             set removeSilently 1
  446.             break
  447.             }
  448.             "cancel" {return}
  449.         }
  450.         }
  451.     }
  452.     }
  453.     message "No$word files found"
  454. }
  455.  
  456. #--------------------------------------------------------------------------
  457. # Utility procs:
  458. #--------------------------------------------------------------------------
  459.  
  460. # Find a LaTeX auxiliary file with extension $ext.  If 'forcecurrent' 
  461. # is true, search the current directory without checking for TeX filesets.
  462. #
  463. proc findAuxiliaryFile {ext {forcecurrent 0}} {
  464.     
  465.     set currentWin [win::Current]
  466.     if { $currentWin == "" } { return "" }
  467.     set currentDoc [file tail $currentWin]
  468.     
  469.     if {$forcecurrent} {
  470.     # pretend there are no TeX filesets:
  471.     set fset ""
  472.     } else {
  473.     set fset [isWindowInFileset $currentWin "tex"]
  474.     }
  475.     
  476.     if { $fset != "" } {
  477.     
  478.     set currentWin [texFilesetBaseName $fset]
  479.     set currentDoc [file tail $currentWin]
  480.     set currentDir [file dirname $currentWin]
  481.     set docBasename [file rootname $currentDoc]
  482.     set lowerExt [string tolower $ext]
  483.     
  484.     } else {
  485.     
  486.     # we do all this if it's not a project:
  487.     set currentDir [file dirname $currentWin]        
  488.     set docBasename [file rootname $currentDoc]
  489.     set lowerExt [string tolower $ext]
  490.     
  491.     # Is the window untitled or dirty?
  492.     global PREFS
  493.     if { [set num [winUntitled]] } {
  494.         set filename [file join $PREFS tmp Untitled$num\.$lowerExt]
  495.         if { [file exists $filename] } {
  496.         return $filename
  497.         } else {
  498.         return ""
  499.         }
  500.     } elseif { [winDirty] } {
  501.         switch [askyesno "Window dirty---continue anyway?"] {
  502.         "yes" {
  503.             set filename [file join $PREFS tmp temp-$currentDoc\.$lowerExt]
  504.             if { [file exists $filename] } {
  505.             return $filename
  506.             } else {
  507.             # fall through
  508.             }
  509.         }
  510.         "no" {return ""}
  511.         }
  512.     }
  513.     }
  514.     
  515.     # Check the current directory:
  516.     set filename [file join $currentDir $docBasename\.$lowerExt]
  517.     if { [file exists $filename] } {
  518.     return $filename
  519.     } else {
  520.     return ""
  521.     }
  522. }
  523.  
  524. # If the current window is untitled, return its number (i.e., either
  525. # the number 1 or the number  n  in "Untitled <n>"); otherwise, return 0.
  526. proc winUntitled {} {
  527.     set currentWin [win::Current]
  528.     if { $currentWin == "" } { return 0 }
  529.     set currentDoc [file tail $currentWin]
  530.     if { [string match $currentWin $currentDoc] } {
  531.     if { [regexp {<(.*)>} $currentDoc dummy num] } {
  532.         return $num
  533.     } else {
  534.         return 1
  535.     }
  536.     } else {
  537.     return 0
  538.     }
  539. }
  540.  
  541. ## 
  542.  # -------------------------------------------------------------------------
  543.  # 
  544.  # "texApp" --
  545.  # 
  546.  #  Switch to bibtex, latex or makeindex
  547.  # -------------------------------------------------------------------------
  548.  ##
  549. proc texApp {name} {
  550.     set type [string tolower $name]
  551.     global ${type}Sig ${type}AppSignatures
  552.     set supportedApps [array names ${type}AppSignatures]
  553.     foreach app $supportedApps { eval lappend sigs [set ${type}AppSignatures($app)] }
  554.     set longPrompt "Please locate your ${name} app."
  555.     if { [catch {app::launchAnyOfThese $sigs ${type}Sig $longPrompt} appname] } {
  556.     error "bug in 'app::launchAnyOfThese'"
  557.     }
  558.     set quotedSig "'[string trim [set ${type}Sig] {'}]'"
  559.     switchTo $quotedSig
  560. }
  561.  
  562.  
  563.  
  564.  
  565.  
  566.  
  567.  
  568.  
  569.  
  570.